/*
Pyxis 2.0
Copyright 2010-2011 Thomas W. Holtquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections;

using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Skewworks.Pyxis.EXT;
using Skewworks.Pyxis.Kernel;

namespace Skewworks.Pyxis.GUI.Controls
{

    [Serializable]
    public class Picturebox : Control
    {

        #region Variables

        private ScaleMode _scale = ScaleMode.Normal;
        private bool _autosize = true;
        private BorderStyle _border = BorderStyle.Border3D;
        private Color _bkg = Colors.DarkGray;
        private Bitmap _bmp = null;

        #endregion

        #region Constructors

        public Picturebox(Bitmap image, int x, int y)
        {
            _bmp = image;
            _x = x;
            _y = y;
        }

        public Picturebox(Bitmap image, int x, int y, int width, int height)
        {
            _bmp = image;
            _x = x;
            _y = y;
            _w = width;
            _h = height;
            _autosize = false;
        }

        public Picturebox(Bitmap image, int x, int y, int width, int height, BorderStyle border, ScaleMode scale)
        {
            _bmp = image;
            _x = x;
            _y = y;
            _w = width;
            _h = height;
            _autosize = false;
            _border = border;
            _scale = scale;
        }

        #endregion

        #region  Properties

        public bool AutoSize
        {
            get { return _autosize; }
            set { _autosize = value; Render(true); }
        }

        public Color Background
        {
            get { return _bkg; }
            set { _bkg = value; Render(true); }
        }

        public ScaleMode ScaleMode
        {
            get { return _scale; }
            set { _scale = value; Render(true); }
        }

        public BorderStyle BorderStyle
        {
            get { return _border; }
            set { _border = value; Render(true); }
        }

        public Bitmap Image
        {
            get { return _bmp; }
            set { _bmp = value; Render(true); }
        }

        #endregion

        #region GUI

        public override void Render(bool flush)
        {
            if (_parent == null || _parent.ScreenBuffer == null || !_visible || _suspend) return;

            int dsW, dsH, dX, dY;

            // Set clipping region in case we're off parent somewhere (can happen w/ scroll)
            _parent.ScreenBuffer.SetClippingRectangle(_parent.Left, _parent.Top, _parent.Width, _parent.Height);

            // Get Border offset
            int bOffset = 0;
            switch (_border)
            {
                case BorderStyle.Border3D:
                    bOffset = 2;
                    break;
                case BorderStyle.BorderFlat:
                    bOffset = 1;
                    break;
            }

            // Check auto-size first
            if (_autosize)
            {
                _w = _bmp.Width + bOffset + bOffset;
                _h = _bmp.Height + bOffset + bOffset;
            }

            // Render border & background
            switch (_border)
            {
                case BorderStyle.Border3D:
                    _parent.ScreenBuffer.DrawRectangle(Colors.White, 1, Left, Top, _w, _h, 0, 0, _bkg, 0, 0, _bkg, 0, 0, 256);
                    _parent.ScreenBuffer.DrawRectangle(Colors.Gray, 0, Left + 1, Top + 1, _w - 2, _h - 2, 0, 0, _bkg, 0, 0, _bkg, 0, 0, 256);
                    break;
                case BorderStyle.BorderFlat:
                    _parent.ScreenBuffer.DrawRectangle(Colors.Black, 1, Left, Top, _w, _h, 0, 0, _bkg, 0, 0, _bkg, 0, 0, 256);
                    break;
                case BorderStyle.BorderNone:
                    _parent.ScreenBuffer.DrawRectangle(_bkg, 0, Left, Top, _w, _h, 0, 0, _bkg, 0, 0, _bkg, 0, 0, 256);
                    break;
            }

            // Render Image
            if (_bmp != null)
            {
                rect Region = rect.intersect(new rect(_parent.Left, _parent.Top, _parent.Width, _parent.Height), new rect(Left + bOffset, Top + bOffset, _w - bOffset - bOffset, _h - bOffset - bOffset));
                _parent.ScreenBuffer.SetClippingRectangle(Region.X, Region.Y, Region.Width, Region.Height);
                switch (_scale)
                {
                    case ScaleMode.Normal:
                        _parent.ScreenBuffer.DrawImage(Left + bOffset, Top + bOffset, _bmp, 0, 0, _bmp.Width, _bmp.Height);
                        break;
                    case ScaleMode.Stretch:
                        _parent.ScreenBuffer.DrawImage(Left + bOffset, Top + bOffset, _bmp, 0, 0, _w - bOffset - bOffset, _h - bOffset - bOffset);
                        break;
                    case ScaleMode.Scale:
                        float multiplier;
                        int dH = _h - bOffset - bOffset;
                        int dW = _w - bOffset - bOffset;


                        if (_bmp.Height > _bmp.Width)
                        {
                            // Portrait
                            if (dH > dW)
                            {
                                multiplier = (float)dW / (float)_bmp.Width;
                            }
                            else
                            {
                                multiplier = (float)dH / (float)_bmp.Height;
                            }
                        }
                        else
                        {
                            // Landscape
                            if (dH > dW)
                            {
                                multiplier = (float)dW / (float)_bmp.Width;
                            }
                            else
                            {
                                multiplier = (float)dH / (float)_bmp.Height;
                            }
                        }

                        dsW = (int)((float)_bmp.Width * multiplier);
                        dsH = (int)((float)_bmp.Height * multiplier);
                        dX = Left + bOffset + (int)((float)dW / 2 - (float)dsW / 2);
                        dY = Top + bOffset + (int)((float)dH / 2 - (float)dsH / 2);

                        _parent.ScreenBuffer.DrawImage(dX, dY, _bmp, 0, 0, dsW, dsH);
                        break;
                    case Pyxis.ScaleMode.Center:
                        dX = _w / 2 - _bmp.Width / 2;
                        dY = _h / 2 - _bmp.Height / 2;
                        _parent.ScreenBuffer.DrawImage(dX, dY, _bmp, 0, 0, _bmp.Width, _bmp.Height);
                        break;
                    case Pyxis.ScaleMode.Tile:
                        for (dX = 0; dX < _w; dX += _bmp.Width)
                        {
                            for (dY = 0; dY < _h; dY += _bmp.Height)
                                _parent.ScreenBuffer.DrawImage(dX, dY, _bmp, 0, 0, _bmp.Width, _bmp.Height);
                        }
                        break;
                }
            }

            if (flush)
            {
                _parent.ScreenBuffer.Flush(Left, Top, _w, _h);
                _parent.ScreenBuffer.SetClippingRectangle(0, 0, AppearanceManager.ScreenWidth, AppearanceManager.ScreenHeight);
            }
        }

        #endregion

    }
}
